using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace WPCoco
{
    /// <summary>
    /// Struct that store a portion of one texture
    /// </summary>
    public struct TextureFrame : ITextured
    {
        #region ITextured Members

        RectangleF textureRegionNormalized;

        public RectangleF TextureRegionNormalized
        {
            get { return textureRegionNormalized; }
            set 
            { 
                textureRegionNormalized = value;
                if (texture != null)
                    textureRegion = new Rectangle((int)(textureRegionNormalized.X * Texture.Width),
                                                  (int)(textureRegionNormalized.Y * Texture.Height),
                                                  (int)(textureRegionNormalized.Width * Texture.Width),
                                                  (int)(textureRegionNormalized.Height * Texture.Height));
            }
        }

        private Rectangle textureRegion;

        public Rectangle TextureRegion
        {
            get { return textureRegion; }
            set 
            { 
                textureRegion = value;
                if (texture != null)
                    textureRegionNormalized = new RectangleF((float)textureRegion.X / (float)Texture.Width,
                                                             (float)textureRegion.Y / (float)Texture.Height,
                                                             (float)textureRegion.Width / (float)Texture.Width,
                                                             (float)textureRegion.Height / (float)Texture.Height);

                else
                    textureRegionNormalized = new RectangleF();
            }
        }

        private Texture2D texture;

        public Texture2D Texture
        {
            get { return texture; }
            set 
            { 
                texture = value;
                if (texture != null)
                    textureRegionNormalized = new RectangleF((float)textureRegion.X / (float)Texture.Width,
                                                             (float)textureRegion.Y / (float)Texture.Height,
                                                             (float)textureRegion.Width / (float)Texture.Width,
                                                             (float)textureRegion.Height / (float)Texture.Height);

                else
                    textureRegionNormalized = new RectangleF();
            }
        }

        private Trim textureTrim;

        public Trim TextureTrim
        {
            get { return textureTrim; }
            set { textureTrim = value; }
        }

        public Size Size 
        { 
            get
            {
                return new Size(textureRegion.Width + textureTrim.TotalWidth, textureRegion.Height + textureTrim.TotalHeight);
            }
        }

        public void SetTextureFrame(TextureFrame frame) 
        {
            Texture = frame.Texture;
            TextureRegion = frame.TextureRegion;
            TextureTrim = frame.TextureTrim;
        }

        #endregion

        /// <summary>
        /// Return a normalized rectangle of the region
        /// </summary>
        /// <param name="region">Region of texture</param>
        /// <param name="texture">Texture referred</param>
        /// <returns>Normalized rectangle</returns>
        public static RectangleF NormalizeTextureRegion(Rectangle region, Texture2D texture)
        {
            RectangleF rectf = new RectangleF((float)region.X / (float)texture.Width,
                                              (float)region.Y / (float)texture.Height,
                                              (float)region.Width / (float)texture.Width,
                                              (float)region.Height / (float)texture.Height);
            return rectf;
        }

        /// <summary>
        /// Create a texture frame that cover the whole texture
        /// </summary>
        /// <param name="texture">Texture referred</param>
        public static TextureFrame CreateFromTexture(Texture2D texture) 
        {
            TextureFrame frame = new TextureFrame();
            frame.Texture = texture;
            frame.TextureRegion = new Rectangle(0, 0, texture.Width, texture.Height);
            return frame;
        }

        /// <summary>
        /// Return a texture frame from triming a texture
        /// </summary>
        /// <param name="trim">Trim data</param>
        public TextureFrame TrimTextureRegion(Trim trim) 
        {
            TextureFrame frame = this;
            frame.TextureRegion = new Rectangle(textureRegion.X + trim.Left, textureRegion.Y + trim.Top, textureRegion.Width - trim.TotalWidth, textureRegion.Height - trim.TotalHeight);
            return frame;
        }

        public override string ToString()
        {
            return string.Format("Region = [{0}], Trim = [{1}]", textureRegion, textureTrim);
        }
    }
}
